/**
 * 
 */
package com.samh.openrower2;

import java.util.ArrayList;
import java.util.List;


import com.samh.openrower2.ANTPlusService.LocalBinder;
import com.samh.openrower2.R;
import com.samh.openrower2.util.SpeedHandler;

import android.os.Handler;
import android.app.Activity;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Chronometer;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.Color;
import android.widget.Button;



/**
 * @author samh
 *
 */
public class DashboardActivity extends Activity implements OnSharedPreferenceChangeListener {
	
	private static final String TAG = "DashboardActivity";
	private Chronometer mChrono;
	private StopWatchService mStopWatch;
	private IntentFilter filter = new IntentFilter(StrokeRateReceiver.STROKE_DETECTED);
	private StrokeRateReceiver receiver = new StrokeRateReceiver();
	private SensorService mSensorService;
	private Intent mSensorServiceIntent;
	private Handler mHandler = new Handler();
	private SpeedHandler mSpeedHandler = new SpeedHandler(); 
	private double strokeRate = 0;
	private String strokeRateString = "0";
	private long strokeCount = 0;
	private float speed = 0.0f;
	private long distance = 0;
	private String split = "0:00";
	private String averageSplit = "0:00";
	private float gpsAccuracy = 0f;
	private String heartRate = "--";
	private boolean autoStartStandby = false;
	private boolean pieceActive = false;

	
	private boolean mBound;
	
	public SharedPreferences preferences;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.main);
		
		mChrono = (Chronometer) findViewById(R.id.elapsed_time);
		
		mStopWatch = new StopWatchService();
		
		mSensorServiceIntent = new Intent(this, SensorService.class);
		
		preferences = PreferenceManager.getDefaultSharedPreferences(this);
		
		preferences.registerOnSharedPreferenceChangeListener(this);
		
		Log.d(TAG,"Dashboard onCreate");
	}
	
	
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		startService(mSensorServiceIntent);
		bindService(mSensorServiceIntent, mSensorConnection, BIND_AUTO_CREATE);
		registerReceiver(receiver, filter);
		// this breaks mSensorService.getSpeedSensor().startGpsListener(mSensorService);
	}
	
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		//mSensorService.getSpeedSensor().stopGpsListener();
		unregisterReceiver(receiver);
		unbindService(mSensorConnection);
		stopService(mSensorServiceIntent);
	}
	
	private void showReadyButton() {
		Button startButton = (Button) findViewById(R.id.button_start);
		startButton.setText(R.string.Text_Ready);
		startButton.setClickable(true);
		startButton.setBackgroundColor(Color.YELLOW);
	}
	
	private void showResetButton() {
		Button stopButton = (Button) findViewById(R.id.button_stop);
		stopButton.setText(R.string.Text_Reset);
		stopButton.setBackgroundColor(Color.rgb(0,166,255));
	}
	
	private void showStartButton() {
		Button startButton = (Button) findViewById(R.id.button_start);
		startButton.setText(R.string.Text_Start);
		startButton.setBackgroundColor(Color.rgb(255, 145, 0));
	}
	
	private void showStopButton() {
		Button stopButton = (Button) findViewById(R.id.button_stop);
		stopButton.setText(R.string.Text_Stop);
		stopButton.setBackgroundColor(Color.RED);
	}
	
	private void showGoButton() {
		Button startButton = (Button) findViewById(R.id.button_start);
		startButton.setText(R.string.Text_Go);
		startButton.setBackgroundColor(Color.GREEN);
	}
	
	private void resetEverything() {
		
		mStopWatch.reset(mChrono);
		
		mSensorService.reset();
		
		mSensorService.getSpeedSensor().resetAverageSpeed();
		
		resetDisplay();
	}
	
	public void buttonReadyStart(View view) {
		
		if(!autoStartStandby) { // READY state
			
			autoStartStandby = true;
			
			showStartButton();
			
			showStopButton();
		}
		else
		{ // START state
			startPiece();
			autoStartStandby = false;
		}
	}
	
	public void buttonStopReset(View view) {
		
		if(mStopWatch.running) {
			
			stopPiece();
			
		} else {
			
			resetEverything();
			
		}
		
	}
	
	private void startPiece() {
		
		if(!pieceActive) {
		
			startStopWatch();
		
			mSensorService.getSpeedSensor().startUpdatingDistance();
		
			mSensorService.getStrokeSensor().startCountingStrokes();
		
			showStopButton();
		
			showGoButton();
			
			mHandler.post(updateLoop);
			
			pieceActive = true;
			
		}
	}
	
	private void stopPiece() {
		
		if(pieceActive) {
			
			mStopWatch.stop(mChrono);
			
			mSensorService.getSpeedSensor().stopUpdatingDistance();
			
			mSensorService.getStrokeSensor().stopCountingStrokes();
			
			autoStartStandby = false;
			
			showReadyButton();
			
			showResetButton();
			
			mHandler.removeCallbacks(updateLoop);
			
			pieceActive = false;
			
			
			
		}
		
	}
	

	private void startStopWatch() {
		if(!mStopWatch.running) {
			mStopWatch.start(mChrono);
			View button = (View) findViewById(R.id.button_start);
			button.setClickable(false);
		}
	}
	
	
	

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	// TODO Auto-generated method stub
    	//return super.onCreateOptionsMenu(menu);
		Log.d(TAG,"Options Menu Created");
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.menu_dashboard, menu);
    	return true;
    }
    
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case R.id.menu_settings :
			Log.d(TAG,"Settings Menu Selected");
			startActivity(new Intent(this, SettingsActivity.class));
			return true;
		case R.id.menu_session :
			Log.d(TAG,"Session Menu Selected");
			startActivity(new Intent(this, SessionActivity.class));
			return true;
		default :
			return super.onOptionsItemSelected(item);
		}
		
	}
	
    public class StrokeRateReceiver extends BroadcastReceiver {
    	
    	public final static String STROKE_DETECTED = "com.samh.openrower2.STROKE_DETECTED";
    	public final static String STROKE_RATE = "com.samh.openrower2.STROKE_RATE";
    	public final static String STROKE_COUNT = "com.samh.openrower2.STROKE_COUNT";
    	public final static String STROKE_RATE_STRING = "com.samh.openrower2.STROKE_RATE_STRING";
    	
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		
    		// CURRENT STROKE RATE
    		strokeRate = intent.getDoubleExtra(STROKE_RATE,0);
    		
    		// CURRENT STROKE RATE STRING
    		strokeRateString = intent.getStringExtra(STROKE_RATE_STRING);
    		
    		// CURRENT STROKE COUNT
    		strokeCount = intent.getLongExtra(STROKE_COUNT, 0);
    		
    		if(autoStartStandby) {
    			startPiece();
    		}
        	    		
    		updateDisplay();
    		
    	}
    }
    
    private final ServiceConnection mSensorConnection = new ServiceConnection() {
		
    	private final static String TAG = "mSensorConnection";
    	
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			SensorService.LocalBinder binder = (SensorService.LocalBinder) service;
			mSensorService = binder.getService();
			resetDisplay();
		}
	};

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		// TODO Auto-generated method stub
		Log.d(TAG, "prefs"+sharedPreferences);
		
	}
	
	public void updateDisplay() {
		
		// Update the location
		mSensorService.getSpeedSensor().updateLocation();
		
    	// CURRENT SPEED
    	speed = mSensorService.getSpeedSensor().getLastSpeed();
    	
    	// CURRENT RAW SPEED
    	float rawSpeed = mSensorService.getSpeedSensor().getLastRawSpeed();
    	
    	// AVERAGE SPLIT
    	float averageSpeed = mSensorService.getSpeedSensor().getAverageSpeed();
		averageSplit = mSpeedHandler.convertSpeedToSplit(averageSpeed);
		
    	// CURRENT SPLIT
		split = mSpeedHandler.convertSpeedToSplit(speed);
		
		// CURRENT GPS ACCURACY
		gpsAccuracy = mSensorService.getSpeedSensor().getLastAccuracy();
		
		//CURRENT DISTANCE
		distance = (long) mSensorService.getSpeedSensor().getDistance();
		
		heartRate = "0";
		
		displayStrokeRate(strokeRateString);
		
		displayStrokeCount(Long.toString(strokeCount));
		
		displayDistance(distance);
		
		displayCurrentSplit(split);
		
		displayAverageSplit(averageSplit);
		
		displayHeartRate(heartRate);
		
		displayGpsAccuracy(gpsAccuracy);
		
		displaySpeedMS(rawSpeed);
		
	}
		
	public void resetDisplay() {
    	
		displayDistance(0);
    	
    	displayStrokeCount("0");
    	
    	displayAverageSplit("0:00");
    	
    	displayCurrentSplit("-:--");
    	
    	displayStrokeRate("0");
    	
    	displayHeartRate("--");
    	
    	displayGpsAccuracy(gpsAccuracy);
    	
    	displaySpeedMS(0.0f);
    	
    	showStopButton();
    	
    	showReadyButton();
    }
	
    
    private void displayDistance(long distance) {
    	
    	String metres = String.format("%05d",distance);
		
        TextView mDistance = (TextView) findViewById(R.id.value_distance);
        
        mDistance.setText(metres);
    }
    
    private void displayStrokeCount(String count) {
        
        TextView mStrokeCount = (TextView) findViewById(R.id.value_stroke_count);
        
        mStrokeCount.setText(count);
        
    }
    
    private void displayAverageSplit(String split) {
    	
    	TextView elapsed_time = (TextView) findViewById(R.id.value_average_split);
    	
    	elapsed_time.setText(split);

    }
    
    private void displaySpeedMS(float speed) {
    	
    	double s = Math.round(speed * 100);
    	
    	double r = s / 100;
    	
    	TextView raw_speed = (TextView) findViewById(R.id.view_speed_ms);
    	
    	raw_speed.setText(Double.toString(r));
    }
    
    private void displayCurrentSplit(String split) {
    	
    	if(gpsAccuracy > mSensorService.getSpeedSensor().MIN_ACCURACY | gpsAccuracy < 1.0f) {
    		split = "0:00";
    	}
    	
    	TextView elapsed_time = (TextView) findViewById(R.id.value_500m_split);
    	
    	elapsed_time.setText(split);
    }
    
    private void displayStrokeRate(String spm) {
    	
    	TextView elapsed_time = (TextView) findViewById(R.id.value_stroke_rate);
    	
    	elapsed_time.setText(spm);
    }
    
    private void displayHeartRate(String hr) {
    	
    	TextView elapsed_time = (TextView) findViewById(R.id.value_heart_rate);
    	
    	elapsed_time.setText(hr);
    }
    
    private void displayGpsAccuracy(float accuracy) {
    	
    	String strAccuracy = "";
    	
    	if(gpsAccuracy > mSensorService.getSpeedSensor().MIN_ACCURACY | gpsAccuracy < 1.0f) {
    		strAccuracy = "waiting...";
    	} else {
    		strAccuracy = Float.toString(accuracy);
    	}
    	
    	TextView pbSignalStrength = (TextView) findViewById(R.id.value_gps_signal);
    	
		pbSignalStrength.setText(strAccuracy);
    	
    }
    
    Runnable updateLoop = new Runnable() {
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
						
			updateDisplay();
			
			mHandler.postDelayed(this, 1000);
		}
	};

   
	
}


